package main

import (
	"fmt"
	"sync"
	"time"
)

type CtrlGroup struct {
	ch chan struct{}
	wg sync.WaitGroup
}

func (g *CtrlGroup) enter() {
	g.ch <- struct{}{}
}

func (g *CtrlGroup) leave() {
	<-g.ch
}

func (g *CtrlGroup) Go(f func()) {
	g.enter() // 接收到新任务, 发送到channel中, 如果channel 满了需要等待
	g.wg.Add(1)
	go func() {
		defer g.leave()
		defer g.wg.Done()
		f()
	}()
	g.wait()
}

func (g *CtrlGroup) wait() {
	g.wg.Wait()
}

func NewCtrlGroup(num int) *CtrlGroup {
	return &CtrlGroup{
		ch: make(chan struct{}, num),
	}
}

func main() {
	start := time.Now()
	var ctrlGroup = NewCtrlGroup(1)
	for i := 0; i < 10; i++ {
		ctrlGroup.Go(func() {
			fmt.Printf("this is a %d ... \n", i)
		})
		// time.Sleep(time.Second)
	}
	fmt.Println(time.Since(start))
}
